<template>
  <el-upload
    ref="uploadRef"
    :auto-upload="false"
    :before-upload="beforeUpload"
    :on-change="handleChange"
    :on-success="handleSuccess"
    :on-error="handleError"
    multiple
    :accept="accept"
    :show-file-list="false"
    :limit="limit"
  >
    <slot>
      <span class="upload-btn">上传</span>
    </slot>
  </el-upload>
</template>

<script lang="ts" setup>
import { PropType, ref, watch } from 'vue';
import { ElMessage, ElUpload } from 'element-plus';
import type { UploadInstance, UploadFile } from 'element-plus'

const props = defineProps({
  controlLoading: {
    type: Function,
    default: false
  },
  handelUpload: {
    type: Function as PropType<(formData: FormData) => Promise<any>>,
    required: true
  },
  accept: {
    type: String,
    default: '.doc,.docx,.pdf,.txt,.xls,.xlsx,.ppt,.pptx,.jpg,.jpeg,.png' // 默认接受的文件类型
  },
  maxFileSize: {
    type: Number,
    default: 5 * 1024 * 1024 // 默认限制为5MB
  },
  limit: {
    type: Number,
    default: 5 // 默认最多上传5个文件
  },
});

const emits = defineEmits(['success']);

const uploadRef = ref<UploadInstance | null>(null)
const fileList = ref<UploadFile[]>([])
const uploading = ref(false)

watch(() => fileList.value.length, (newVal) => {
  console.log('fileList watch', newVal);
  submitUpload()
})

const beforeUpload = (file: File) => {
  console.log('beforeUpload',file);
  
  // 可以在这里进行文件类型和大小的校验
  const isDocOrPdf = file.type === 'application/vnd.openxmlformats-officedocument.wordprocessingml.document'
   || file.type === 'application/pdf';
  if (fileList.value.length >= props.limit) {
    ElMessage.error(`最多只能上传 ${props.limit} 个文件!`);
    return false;
  }
  if (!isDocOrPdf) {
    ElMessage.error('上传格式不正确!');
    return false;
  }
  if (file.size / 1024 / 1024 > props.maxFileSize) { // 限制文件大小不超过5MB
    ElMessage.error('上传头像大小不能超过 5MB!');
    return false;
  }
  return true;
};

// 提交上传
const submitUpload = async () => {
  if (fileList.value.length === 0) return
  try {
    const formData = new FormData()
    
    fileList.value.forEach(file => {
      formData.append('files', file.raw as any)
    })
    props.controlLoading(true)
    const res = await props.handelUpload(formData)

    ElMessage.success('上传成功！')
    fileList.value.forEach(file => {
      file.status = 'success'
    })
    emits('success', {fileList: [...fileList.value], response: res.data})
  } catch (error) {
    ElMessage.error('上传失败')
    fileList.value.forEach(file => {
      file.status = 'fail'
    })
  } finally {
    props.controlLoading(false)
    clearFiles();
  }
}

// 文件选择回调
const handleChange = (file: UploadFile) => {
  const index = fileList.value.findIndex(f => f.uid === file.uid)
  if (index !== -1) {
    fileList.value[index] = file
  } else {
    fileList.value.push(file)
  }
}

// 成功回调
const handleSuccess = (response: any, file: UploadFile) => {
  ElMessage.success(`文件 ${file.name} 上传成功！`)
  file.status = 'success'
}

// 错误回调
const handleError = (err: any, file: UploadFile) => {
  ElMessage.error(`文件 ${file.name} 上传失败：${err.message}`)
  file.status = 'fail'
}

// 清空文件列表
const clearFiles = () => {
  fileList.value = []
  uploadRef.value?.clearFiles()
}

</script>

<style lang="scss" scoped>
.upload-component {
  /* 添加样式 */
  .upload-btn {
      padding: 10px 22px;
      border-radius: 6px;
      background: linear-gradient( 91deg, #EB1426 0%, #FF6D70 100%);
      color: white;
    }
}
</style>